/**
Nectarine Utility Project is a software interface for the web system 'demovibes'
Copyright (C) 2010  Alexandre LAURENT

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.

website: http://code.google.com/p/nectarine-utility-project/
e-mail: lw.demoscene@gmail.com
**/

#include "favsdialog.h"

#include <QDialog>
#include <QWidget>
#include <QList>
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QLabel>
#include <QFrame>
#include <QTableWidget>
#include <QHeaderView>
#include <QPushButton>
#include <QSpinBox>

#include <QSignalMapper>

#include "Types/favorite.h"

#include "globals.h"

FavsDialog :: FavsDialog(const Favorites& favorites, const bool isOwner/*=false*/, const QList<int>& ownerFavList/* = QList<int>()*/, const bool isConnected/*=false*/, QWidget* parent/*=0*/)
    :QDialog(parent),owner(favorites.owner),isOwner(isOwner),nbPages(favorites.nbPages),currentPage(1)
{
    this->setWindowTitle(tr("%1's favs : NUP :: Favorite viewer").arg(favorites.owner));
    this->setWindowIcon(QIcon(ICONSDIR + QString("heart.png")));
    this->resize(600,600);

    pMainGrid = new QVBoxLayout(this);

    pTitleLabel = new QLabel(tr("<h3><b>%1's Favorites</b> <small>(%2 songs)</small></h3>").arg(favorites.owner).arg(favorites.favs.size()),this);
    pHLine1 = new QFrame(this);
    pHLine1->setFrameStyle(QFrame::HLine);
    pHLine1->setLineWidth(1);

    pFavsTable = new QTableWidget(favorites.favs.size(),8,this);
    pFavsTable->setHorizontalHeaderLabels(QStringList() << tr("Song") << tr("Artists") << tr("State") << tr("Note") << tr("Last time requested") << tr("Req") << tr("Fav") << tr("Id"));
    pFavsTable->setAlternatingRowColors(true);
    pFavsTable->setColumnHidden(7,true); // Hidden this column because it contains only information for the app
    pFavsTable->setEditTriggers(QAbstractItemView::NoEditTriggers);

    pRequestMapper = new QSignalMapper(this);
    pFavMapper = new QSignalMapper(this);
    pUnFavMapper = new QSignalMapper(this);

    loadFavs(favorites, ownerFavList);

    QHeaderView* pHeaderView = pFavsTable->horizontalHeader();
    pHeaderView->setResizeMode(0,QHeaderView::Stretch);
    pHeaderView->setResizeMode(1,QHeaderView::Stretch);
    pHeaderView->setResizeMode(2,QHeaderView::ResizeToContents);
    pHeaderView->setResizeMode(3,QHeaderView::ResizeToContents);
    //pHeaderView->setResizeMode(5,QHeaderView::ResizeToContents);
    pHeaderView->setResizeMode(5,QHeaderView::Fixed);
    pHeaderView->resizeSection(5,25);
    pHeaderView->setResizeMode(6,QHeaderView::ResizeToContents);

    pFavsTable->verticalHeader()->hide();

    if ( isConnected == false )
    {
        pFavsTable->setColumnHidden(5,true);
        pFavsTable->setColumnHidden(6,true);
    }

    if ( nbPages > 1 )
    {
        pHLine2 = new QFrame(this);
        pHLine2->setFrameStyle(QFrame::HLine);
        pHLine2->setLineWidth(1);

        pButtonGrid = new QHBoxLayout();
        pPreviousPageButton = new QPushButton(tr("<"),this);
        pPreviousPageButton->setEnabled(false);
        pNextPageButton = new QPushButton(tr(">"),this);
        pPageLabel = new QLabel(tr("Page:"),this);
        pPageInput = new QSpinBox(this);
        pPageInput->setRange(1,nbPages);
        pPageInput->setValue(1);
        pPageMaximumLabel = new QLabel(this);
        pGoPageButton = new QPushButton(tr("Go"),this);
    }

    pValidateButton = new QPushButton(tr("Ok"),this);

    pMainGrid->addWidget(pTitleLabel,0,Qt::AlignHCenter);
    pMainGrid->addWidget(pHLine1);
    pMainGrid->addWidget(pFavsTable);
    if ( nbPages > 1 )
    {
        pMainGrid->addWidget(pHLine2);
        pMainGrid->addLayout(pButtonGrid);
        pButtonGrid->addWidget(pPreviousPageButton);
        pButtonGrid->addWidget(pNextPageButton);
        pButtonGrid->addWidget(pPageLabel);
        pButtonGrid->addWidget(pPageInput);
        pButtonGrid->addWidget(pPageMaximumLabel);
        pButtonGrid->addWidget(pGoPageButton);
    }
    pMainGrid->addWidget(pValidateButton);

    connect(pRequestMapper, SIGNAL(mapped(int)), this, SLOT(checkRequest(int)));
    connect(pFavMapper, SIGNAL(mapped(int)), this, SLOT(checkFav(int)));
    connect(pUnFavMapper, SIGNAL(mapped(int)), this, SLOT(checkUnFav(int)));
    connect(pValidateButton, SIGNAL(clicked()), this, SLOT(accept()));

    if ( nbPages > 1 )
    {
        connect(pPreviousPageButton, SIGNAL(clicked()), this, SLOT(previousPage()));
        connect(pNextPageButton, SIGNAL(clicked()), this, SLOT(nextPage()));
        connect(pGoPageButton, SIGNAL(clicked()), this, SLOT(goPage()));
    }

    qDebug() << "FavsDialog created (Owner: " << isOwner << " isConnected: " << isConnected << ")";
}

FavsDialog :: ~FavsDialog(void)
{
    qDebug() << "FavsDialog deleted";
}

void FavsDialog :: loadFavs(const Favorites& favorites, const QList<int>& ownerFavList/* = QList<int>()*/)
{
    unsigned int favsCounter = 0;

    qDebug() << "FavsDialog :: loadFavs";

    pFavsTable->clearContents();
    pFavsTable->setRowCount(favorites.favs.count());

    for ( QList<Favorite>::const_iterator itFav = favorites.favs.begin() ; itFav != favorites.favs.end() ; itFav++ , favsCounter++ )
    {
        pFavsTable->setItem(favsCounter,0,new QTableWidgetItem(itFav->song.title));

        QString artist("");
        for ( QList<Artist>::const_iterator itArtist = itFav->artists.begin() ; itArtist != itFav->artists.end() ; itArtist++ )
        {
            artist += itArtist->nickname + QString(" ");
        }

        pFavsTable->setItem(favsCounter,1,new QTableWidgetItem(artist));

        QTableWidgetItem* pTmpStateItem = new QTableWidgetItem(statusToString(itFav->status));
        pTmpStateItem->setTextAlignment(Qt::AlignCenter);
        pFavsTable->setItem(favsCounter,2, pTmpStateItem);

        QTableWidgetItem* pTmpVoteItem = new QTableWidgetItem(QString("%1").arg(itFav->vote));
        pTmpVoteItem->setTextAlignment(Qt::AlignCenter);
        pFavsTable->setItem(favsCounter,3,pTmpVoteItem);

        QTableWidgetItem* pTmpLRequestItem = new QTableWidgetItem(itFav->lastRequest.toString());
        pTmpLRequestItem->setTextAlignment(Qt::AlignCenter);
        pFavsTable->setItem(favsCounter,4,pTmpLRequestItem);

        qDebug() << "Song: " << itFav->song.title;

        if ( itFav->isRequestable && ( itFav->status == S_ACTIVE ) )
        {
            QPushButton* pTmpRequestButton = new QPushButton(QIcon(ICONSDIR + QString("add.png")),QString(""),this);
            connect(pTmpRequestButton, SIGNAL(clicked()), pRequestMapper, SLOT(map()));
            pRequestMapper->setMapping(pTmpRequestButton,favsCounter);

            pFavsTable->setCellWidget(favsCounter,5,pTmpRequestButton);
        }
        else
        {
            QTableWidgetItem* pTmpRequestItem = new QTableWidgetItem(QIcon(ICONSDIR + QString("lock.png")),QString(""));
            pTmpRequestItem->setTextAlignment(Qt::AlignCenter);
            pFavsTable->setItem(favsCounter,5,pTmpRequestItem);
        }

        if ( isOwner )
        {
            QPushButton* pTmpUnFavButton = new QPushButton(QIcon(ICONSDIR + QString("heart_delete.png")),QString(""),this);
            connect(pTmpUnFavButton, SIGNAL(clicked()), pUnFavMapper, SLOT(map()));
            pUnFavMapper->setMapping(pTmpUnFavButton,favsCounter);

            pFavsTable->setCellWidget(favsCounter,6,pTmpUnFavButton);
        }
        else
        {
            // In case of the connected user, doesn't have this song, he can fav it :)
            if ( !ownerFavList.contains(itFav->song.id) )
            {
                QPushButton* pTmpFavButton = new QPushButton(QIcon(ICONSDIR + QString("heart_add.png")),QString(""),this);
                connect(pTmpFavButton, SIGNAL(clicked()), pFavMapper, SLOT(map()));
                pFavMapper->setMapping(pTmpFavButton,favsCounter);

                pFavsTable->setCellWidget(favsCounter,6,pTmpFavButton);
            }
        }

        QTableWidgetItem* pTmpIdItem = new QTableWidgetItem();
        pTmpIdItem->setData(Qt::UserRole,itFav->song.id);
        pFavsTable->setItem(favsCounter,7,pTmpIdItem);
    }
}

void FavsDialog :: accept(void)
{
    qDebug() << "FavsDialog :: accept";

    this->done(QDialog::Accepted);
    emit deleteFDSignal(this);
}

void FavsDialog :: reject(void)
{
    qDebug() << "FavsDialog :: reject";

    this->done(QDialog::Rejected);
    emit deleteFDSignal(this);
}

void FavsDialog :: checkRequest(int row)
{
    QTableWidgetItem* pTmpRequestItem = new QTableWidgetItem(QIcon(ICONSDIR + QString("lock.png")),QString(""));
    pTmpRequestItem->setTextAlignment(Qt::AlignCenter);

    qDebug() << "FavsDialog :: checkRequest(" << row << ")";

    emit needRequestSong(pFavsTable->item(row,7)->data(Qt::UserRole).toInt());
    //delete (pFavsTable->item(row,5));
    pFavsTable->removeCellWidget(row,5);

    pFavsTable->setItem(row,5,pTmpRequestItem);
}

void FavsDialog :: checkFav(int row)
{
    qDebug() << "FavsDialog :: checkFav(" << row << ")";

    emit needFav(pFavsTable->item(row,7)->data(Qt::UserRole).toInt());
    pFavsTable->removeCellWidget(row,6);
    pFavsTable->setItem(row,6,NULL);

}

void FavsDialog :: checkUnFav(int row)
{
    qDebug() << "FavsDialog :: checkUnFav(" << row << ")";

    emit needUnfav(pFavsTable->item(row,7)->data(Qt::UserRole).toInt());
    //delete (pFavsTable->item(row,6));
    if ( isOwner )
    {
        pFavsTable->setRowHidden(row,true);
        pFavsTable->update();
    }
    // No else, because in all cases we can unfav only in user's favorite list
}

void FavsDialog :: previousPage(void)
{
    qDebug() << "FavsDialog ::  previousPage";

    emit needLoadPage(this,--currentPage);
    if ( currentPage == 1 )
    {
        pPreviousPageButton->setEnabled(false);
    }
    pNextPageButton->setEnabled(true);
}

void FavsDialog :: nextPage(void)
{
    qDebug() << "FavsDialog ::  nextPage";

    emit needLoadPage(this,++currentPage);
    if ( currentPage == nbPages )
    {
        pNextPageButton->setEnabled(false);
    }
    pPreviousPageButton->setEnabled(true);
}

void FavsDialog :: goPage(void)
{
    qDebug() << "FavsDialog ::  goPage ( " << pPageInput->value() << " )";

    if ( static_cast<unsigned int>(pPageInput->value()) > nbPages )
    {
        return;
    }

    emit needLoadPage(this,pPageInput->value());
    currentPage = pPageInput->value();
    if ( currentPage == 1 )
    {
        pPreviousPageButton->setEnabled(false);
    }
    else
    {
        pPreviousPageButton->setEnabled(true);
    }

    if ( currentPage == nbPages )
    {
        pNextPageButton->setEnabled(false);
    }
    else
    {
        pNextPageButton->setEnabled(true);
    }
}
